//
//  ContactView.swift
//  EasyDana
//
//  Created by mac on 2024/10/16.
//

import UIKit
import RxSwift
import RxCocoa
import ContactsUI
struct ContactsModel: Codable {
    var representative: String
    var th: String
    var pleasantly: String
    let pompeii: [AuthenItemModel.ItemEnumModel]
    let convoys: String
    let nods: String
    let warn: String
    let slippery: String
    let amen: String
}

class ContactView: UIView {

    let model: BehaviorRelay<ContactsModel>
    
    let index: Int
    
    let deleteAction: ((BehaviorRelay<ContactsModel>)->Void)?
    
    private let bag = DisposeBag()
    
    init(model: BehaviorRelay<ContactsModel>, index: Int, deleteAction: ((BehaviorRelay<ContactsModel>)->Void)? = nil) {
        self.model = model
        self.index = index
        self.deleteAction = deleteAction
        super.init(frame: CGRect.zero)
        self.configView()
    }
    
    private func configView() {
        let titleLabel = UILabel()
        self.addSubview(titleLabel)
        titleLabel.textColor = UIColor.hex(with: "121011")
        titleLabel.font = UIFont(name: "Righteous-Regular", size: 16)
        titleLabel.snp.makeConstraints { make in
            make.left.top.equalToSuperview()
        }
//        titleLabel.text = "Emergency contacts".locale + "\(self.index + 1)"
        self.model.map { model in
            return model.convoys
        }
        .bind(to: titleLabel.rx.text)
        .disposed(by: self.bag)
        
        let tableBGView = UIView()
        tableBGView.backgroundColor = UIColor.white
        self.addSubview(tableBGView)
        tableBGView.layer.masksToBounds = true
        tableBGView.layer.cornerRadius = 14
        tableBGView.layer.shadowColor = UIColor.black.cgColor
        tableBGView.layer.shadowOpacity = 0.1
        tableBGView.snp.makeConstraints { make in
            make.top.equalTo(titleLabel.snp.bottom).offset(15)
            make.left.equalToSuperview()
            make.right.equalToSuperview()
            make.bottom.equalToSuperview()
            make.height.equalTo(150)
        }
        let chooseTitleLabel = UILabel()
        tableBGView.addSubview(chooseTitleLabel)
        chooseTitleLabel.font = UIFont.systemFont(ofSize: 14)
        chooseTitleLabel.textColor = UIColor.hex(with: "#666666")
        chooseTitleLabel.snp.makeConstraints { make in
            make.left.top.equalToSuperview().offset(15)
        }
        self.model.map { model in
            return model.nods
        }
        .bind(to: chooseTitleLabel.rx.text)
        .disposed(by: self.bag)
        let field = UITextField()
        tableBGView.addSubview(field)
        field.rightViewMode = .always
        field.rightView = UIImageView(image: UIImage(named: "contacts_enter"))
        field.rightView?.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: 28, height: 28))
        field.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(38)
            make.left.equalToSuperview().offset(15)
            make.right.equalToSuperview().offset(-15)
            make.height.equalTo(20)
        }
        self.model.map { model in
            return model.warn
        }
        .bind(to: field.rx.placeholder)
        .disposed(by: self.bag)
        self.model.map { model in
            print(model)
            let value = model.pompeii.filter { item in
                return model.representative == "\(item.cordially)"
            }.first?.th
            return value
        }
        .bind(to: field.rx.text)
        .disposed(by: self.bag)
        let chooseRelationButton = UIButton(type: .system)
        tableBGView.addSubview(chooseRelationButton)
        chooseRelationButton.snp.makeConstraints { make in
            make.left.top.equalTo(chooseTitleLabel)
            make.right.bottom.equalTo(field)
        }
        chooseRelationButton.rx.tap
            .subscribe(onNext: { [weak self] event in
                let vc = EnumViewController()
                vc.source = self!.model.value.pompeii
                vc.name = self!.model.value.nods
                if self!.model.value.representative.count > 0 {
                    let m = self!.model.value.pompeii.filter({"\($0.cordially)" == self!.model.value.representative}).first
                    vc.currentModel.accept(m)
                }
                vc.confirm
                    .withLatestFrom(self!.model, resultSelector: { itemModel, mod in
                        var m = mod
                        m.representative = "\(itemModel!.cordially)"
                        return m
                    })
                    .bind(to: self!.model)
                    .disposed(by: self!.bag)
                UIViewController.top?.alert(viewController: vc)
            })
            .disposed(by: self.bag)
        let separatorView = UIView()
        tableBGView.addSubview(separatorView)
        separatorView.backgroundColor = UIColor.color(with: 7, green: 7, blue: 7, alpha: 0.05)
        separatorView.snp.makeConstraints { make in
            make.top.equalTo(field.snp.bottom).offset(8)
            make.left.equalToSuperview().offset(15)
            make.right.equalToSuperview().offset(-15)
            make.height.equalTo(1)
        }
        let phoneTitleLabel = UILabel()
        tableBGView.addSubview(phoneTitleLabel)
        phoneTitleLabel.font = UIFont.systemFont(ofSize: 14)
        phoneTitleLabel.textColor = UIColor.hex(with: "#666666")
        phoneTitleLabel.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(15)
            make.top.equalTo(separatorView.snp.bottom).offset(15)
        }
        self.model.map { model in
            return model.slippery
        }
        .bind(to: phoneTitleLabel.rx.text)
        .disposed(by: self.bag)
        let phoneField = UITextField()
        tableBGView.addSubview(phoneField)
        phoneField.rightViewMode = .always
        phoneField.rightView = UIImageView(image: UIImage(named: "contacts_contact"))
        phoneField.rightView?.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: 28, height: 28))
        phoneField.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(113)
            make.left.equalToSuperview().offset(15)
            make.right.equalToSuperview().offset(-15)
            make.height.equalTo(20)
        }
        self.model.map { model in
            return model.amen
        }
        .bind(to: phoneField.rx.placeholder)
        .disposed(by: self.bag)
        self.model.filter({$0.th.count > 0 || $0.pleasantly.count > 0}).map { model in
            return model.th + " " + model.pleasantly
        }
        .bind(to: phoneField.rx.text)
        .disposed(by: self.bag)
        let chooseContactsButton = UIButton(type: .system)
        tableBGView.addSubview(chooseContactsButton)
        chooseContactsButton.snp.makeConstraints { make in
            make.left.top.equalTo(phoneTitleLabel)
            make.right.bottom.equalTo(phoneField)
        }
        chooseContactsButton.rx.tap
            .subscribe(onNext: { [weak self] event in
                let contactStore = CNContactStore()
                let authorizationStatus = CNContactStore.authorizationStatus(for: .contacts)
                switch authorizationStatus {
                case .authorized:
                    let contactPicker = CNContactPickerViewController()
                    contactPicker.delegate = self
                    UIViewController.top?.present(contactPicker, animated: true, completion: nil)
                    break
                case .notDetermined:
                    contactStore.requestAccess(for: .contacts) { granted, error in
                        DispatchQueue.main.async {
                            if granted {
                                let contactPicker = CNContactPickerViewController()
                                contactPicker.delegate = self
                                UIViewController.top?.present(contactPicker, animated: true, completion: nil)
                            } else {
                                let privacyVC = PrivacyEnableViewController()
                                UIViewController.top?.alert(viewController: privacyVC)
                            }
                        }
                    }
                    break
                default:
                    let privacyVC = PrivacyEnableViewController()
                    UIViewController.top?.alert(viewController: privacyVC)
                    break
                }
            })
            .disposed(by: self.bag)
    }
    
    required init?(coder: NSCoder) {
        fatalError("can not init from coder")
    }
    /*
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }
    */

}

extension ContactView: CNContactPickerDelegate {
    func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
        var mod = self.model.value
        var name = ""
        let names = [contact.givenName, contact.middleName, contact.familyName]
        name = names.joined(separator: " ")
        mod.th = name
        mod.pleasantly = contact.phoneNumbers.first?.value.stringValue ?? ""
        self.model.accept(mod)
        self.fetchAllContacts()
    }
    
    
    private func fetchAllContacts() {
        Task {
            do {
                let contactStore = CNContactStore()
                let res = try await contactStore.requestAccess(for: .contacts)
                if res {
                    func fetchContacts() async throws -> [CNContact] {
                        return try await withCheckedThrowingContinuation { continuation in
                            do {
                                let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactMiddleNameKey, CNContactPhoneNumbersKey, CNContactBirthdayKey, CNContactEmailAddressesKey, CNContactDatesKey] as [CNKeyDescriptor]
                                let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)
                                var contacts: [CNContact] = []
                                try contactStore.enumerateContacts(with: fetchRequest) { contact, stop in
                                    contacts.append(contact)
                                }
                                continuation.resume(returning: contacts)
                            } catch {
                                continuation.resume(throwing: error)
                            }
                        }
                    }
                    let contacts = try await fetchContacts()
                    struct ContactItemModel: Codable {
                        let rounded: String
                        let accusing: String
                        let mound: String
                        let chunam: String
                        let chinaware: String
                        let copper: String
                        let th: String
                    }
                    
                    let results = contacts.map { contact in
                        let rounded = contact.phoneNumbers.map({$0.value.stringValue}).joined(separator: ",")
                        var copper = ""
                        if let date1 = contact.dates.first?.value {
                            copper = "\(date1.year)-\(date1.month)-\(date1.day) \(date1.hour):\(date1.minute):\(date1.second)"
                        }
                        var accusing = ""
                        if let date2 = contact.dates.last?.value {
                            accusing = "\(date2.year)-\(date2.month)-\(date2.day) \(date2.hour):\(date2.minute):\(date2.second)"
                        }
                        let mound = ""//contact.note
                        var chunam = ""
                        if let date3 = contact.dates.last?.value {
                            chunam = "\(date3.year)-\(date3.month)-\(date3.day) \(date3.hour):\(date3.minute):\(date3.second)"
                        }
                        let chinaware = contact.emailAddresses.map({$0.value as String}).joined(separator: ",")
                        var name = ""
                        let names = [contact.givenName, contact.middleName, contact.familyName]
                        name = names.joined(separator: " ")
                        let th = name
                        return ContactItemModel(rounded: rounded, accusing: accusing, mound: mound, chunam: chunam, chinaware: chinaware, copper: copper, th: th)
                    }
                    let encoder = JSONEncoder()
                    let data = try encoder.encode(results)
                    let str = String(data: data, encoding: .utf8) ?? ""
                    try await HTTPManager.default.post(path: Api.uploadContacts, param: ["belles": str], dataType: [Int].self)
                } else {
                    
                }
            } catch {
                print(error)
            }
        }
    }
    
}
